package com.ocean.clearance.util;

import java.sql.Timestamp;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.time.Instant;
import java.time.LocalDate;
import java.time.ZoneId;
import java.util.Calendar;
import java.util.Date;
import java.util.GregorianCalendar;
import java.util.Locale;

import javax.xml.datatype.DatatypeConfigurationException;
import javax.xml.datatype.DatatypeFactory;
import javax.xml.datatype.XMLGregorianCalendar;

import org.apache.commons.lang3.StringUtils;

public class DateUtil {

	public static final String REG_DATETYPE_1_ENABLENULL = "^((((20[0-3][0-9]-(0[13578]|1[02])-(0[1-9]|[12][0-9]|3[01]))|(20[0-3][0-9]-(0[2469]|11)-(0[1-9]|[12][0-9]|30))) (20|21|22|23|[0-1][0-9]):[0-5][0-9]:[0-5][0-9])|(\\s&&[^\\f\\n\\r\\t\\v])*)$";

	public static final String DATETYPE_1 = "yyyy-MM-dd HH:mm:ss";

	public static final String DATETYPE_2 = "yyyyMMddHHmmssSSS";

	public static final String DATETYPE_3 = "yyyyMMddHHmmss";

	public static final String REG_DATETYPE_4_UNABLENULL = "^(?:(?!0000)[0-9]{4}-(?:(?:0[1-9]|1[0-2])-(?:0[1-9]|1[0-9]|2[0-8])|(?:0[13-9]|1[0-2])-(?:29|30)|(?:0[13578]|1[02])-31)|(?:[0-9]{2}(?:0[48]|[2468][048]|[13579][26])|(?:0[48]|[2468][048]|[13579][26])00)-02-29)$";

	public static final String DATETYPE_4 = "yyyy-MM-dd";

	public static final String DATETYPE_5 = "yyyyMMdd";

	public static final String DATETYPE_6 = "yyMMdd";

	public static final String DATETYPE_7 = "yyyyMMddHH";

	public static final String DATETYPE_8 = "yyyy/MM/dd";

	public static final String DATETYPE_9 = "yyyy-MM-dd EEEE";

	public static final String DATETYPE_10 = "yyyy-MM-dd HH:mm";

	public static final String DATETYPE_11 = "HH:mm yyyy-MM-dd";

	public static final String DATETYPE_12 = "HH:mm";

	public static final String DATETYPE_13 = "MM-dd";

	public static final String DATETYPE_14 = "MM月dd日";

	public static final String DATETYPE_15 = "yyyy";

	public static final String DATETYPE_16 = "MM";

	public static final String DATETYPE_17 = "dd";

	public static final String DATETYPE_18 = "HH";

	public static final String DATETYPE_19 = "mm";

	public static final String DATETYPE_20 = "ss";

	public static final String DATETYPE_21 = "yyMMddHHmm";

	public static final String DATETYPE_22 = "yy/MM/dd HH:mm";

	public static final String DATETYPE_23 = "yyyy-MM-dd ahh:mm:ss";

	public static final String DATETYPE_24 = "yyyy年MM月dd日";

	public static final String DATETYPE_25 = "yyyy/MM/dd HH:mm";

	public static final String DATETYPE_26 = "yyyy-MM";

	public static final String REG_DATETYPE_99_UNABLENULL = "^((?:(?!0000)[0-9]{4}-(?:(?:0[1-9]|1[0-2])-(?:0[1-9]|1[0-9]|2[0-8])|(?:0[13-9]|1[0-2])-(?:29|30)|(?:0[13578]|1[02])-31)|(?:[0-9]{2}(?:0[48]|[2468][048]|[13579][26])|(?:0[48]|[2468][048]|[13579][26])00)-02-29)|(\\s&&[^\\f\\n\\r\\t\\v])*)$";

	public static final String[] WEEK_DESC_1 = { "一", "二", "三", "四", "五", "六", "日" };
	public static final String[] WEEK_DESC_2 = { "星期一", "星期二", "星期三", "星期四", "星期五", "星期六", "星期日" };
	public static final String[] WEEK_DESC_3 = { "周一", "周二", "周三", "周四", "周五", "周六", "周日" };

	public static String format(Date date, String date_type) {
		SimpleDateFormat sdf = new SimpleDateFormat(date_type, Locale.CHINA);
		return sdf.format(date);
	}

	public static Date parse(String date, String date_type) throws ParseException {
		SimpleDateFormat sdf = new SimpleDateFormat(date_type);
		return sdf.parse(date);
	}

	public static Date dateToDate(Date date, String type, String toType) throws ParseException {
		String dateStr = format(date, type);
		return parse(dateStr, toType);
	}

	public static String stringToString(String date, String type, String toType) {
		Date dateTime = null;
		try {
			dateTime = parse(date, type);
		} catch (ParseException e) {
			e.printStackTrace();
		}
		return format(dateTime, toType);
	}

	public static long[] getDistanceTimes(Date one, Date two) {// 两个Date相差的天数，小时数，分钟数
		long day = 0;
		long hour = 0;
		long min = 0;
		long time1 = one.getTime();
		long time2 = two.getTime();
		long diff;
		if (time1 < time2) {
			diff = time2 - time1;
		} else {
			diff = time1 - time2;
		}
		day = diff / (24 * 60 * 60 * 1000);
		hour = (diff / (60 * 60 * 1000) - day * 24);
		min = ((diff / (60 * 1000)) - day * 24 * 60 - hour * 60);
		long[] times = { day, hour, min };
		return times;
	}

	public static Date getrecent2weeksDate() {
		Calendar cal = Calendar.getInstance();
		SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
		cal.set(Calendar.DAY_OF_WEEK, Calendar.MONDAY); // 获取本周一的日期
		cal.set(Calendar.HOUR_OF_DAY, 0);
		cal.set(Calendar.MINUTE, 0);
		cal.set(Calendar.SECOND, 0);
		cal.set(Calendar.MILLISECOND, 0);
		// System.out.println(df.format(cal.getTime()));
		// cal.set(Calendar.DAY_OF_WEEK, Calendar.SUNDAY);//
		// 这种输出的是上个星期周日的日期，因为老外那边把周日当成第一天
		cal.add(Calendar.WEEK_OF_YEAR, -1);// 增加一个星期，才是我们中国人理解的本周日的日期
		System.out.println(df.format(cal.getTime()));
		return cal.getTime();
	}

	public static Date getrecent1weeksDate() {
		Calendar cal = Calendar.getInstance();
		SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
		cal.set(Calendar.DAY_OF_WEEK, Calendar.MONDAY); // 获取本周一的日期
		cal.set(Calendar.HOUR_OF_DAY, 0);
		cal.set(Calendar.MINUTE, 0);
		cal.set(Calendar.SECOND, 0);
		cal.set(Calendar.MILLISECOND, 0);
		// System.out.println(df.format(cal.getTime()));
		// cal.set(Calendar.DAY_OF_WEEK, Calendar.SUNDAY);//
		// 这种输出的是上个星期周日的日期，因为老外那边把周日当成第一天
		System.out.println(df.format(cal.getTime()));
		return cal.getTime();
	}

	public static String secToTime(int time) {// 将秒数转化成XX:XX:XX的时长格式
		String timeStr = null;
		int hour = 0;
		int minute = 0;
		int second = 0;
		if (time <= 0)
			return "00:00";
		else {
			minute = time / 60;
			if (minute < 60) {
				second = time % 60;
				timeStr = unitFormat(minute) + ":" + unitFormat(second);
			} else {
				hour = minute / 60;
				if (hour > 99)
					return "99:59:59";
				minute = minute % 60;
				second = time - hour * 3600 - minute * 60;
				timeStr = unitFormat(hour) + ":" + unitFormat(minute) + ":" + unitFormat(second);
			}
		}
		return timeStr;
	}

	public static String unitFormat(int i) {
		String retStr = null;
		if (i >= 0 && i < 10)
			retStr = "0" + Integer.toString(i);
		else
			retStr = "" + i;
		return retStr;
	}

	/**
	 * 计算currentDate前后相隔dayNum天数，dayNum为负，表示currentDate前dayNum天，currentDate为正，
	 * 表示currentDate后dayNum天
	 * 
	 * @param currentDate
	 *            格式yyyy-MM-dd
	 * @param dayNum
	 *            天数
	 * @return 格式yyyy-MM-dd
	 * @throws ParseException
	 */
	public static String addDay(String currentDate, int dayNum) throws ParseException {
		Calendar calendar = Calendar.getInstance();
		SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
		calendar.setTime(sdf.parse(currentDate));
		calendar.add(Calendar.DAY_OF_YEAR, dayNum);
		return sdf.format(calendar.getTime());
	}

	/**
	 * 计算currentDate前后相隔dayNum天数，dayNum为负，表示currentDate前dayNum天，currentDate为正，
	 * 表示currentDate后dayNum天
	 * 
	 * @param currentTime
	 * @param dayNum
	 * @return 格式yyyy-MM-dd
	 * @throws ParseException
	 */
	public static String addDay(Timestamp currentTime, int dayNum) throws ParseException {
		Calendar calendar = Calendar.getInstance();
		Date currentDate = new Date(currentTime.getTime());
		SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
		calendar.setTime(currentDate);
		calendar.add(Calendar.DAY_OF_YEAR, dayNum);
		return sdf.format(calendar.getTime());
	}

	/**
	 * 计算currentDate前后相隔dayNum天数，dayNum为负，表示currentDate前dayNum天，currentDate为正，
	 * 表示currentDate后dayNum天
	 * 
	 * @param currentDate
	 * @param dayNum
	 * @return 格式yyyy-MM-dd
	 * @throws ParseException
	 */
	public static String addDay(Date currentDate, int dayNum) throws ParseException {
		Calendar calendar = Calendar.getInstance();
		SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
		calendar.setTime(currentDate);
		calendar.add(Calendar.DAY_OF_YEAR, dayNum);
		return sdf.format(calendar.getTime());
	}

	/**
	 * 得到string格式的时间的time
	 * 
	 * @param date
	 * @param pattern
	 * @return
	 * @throws ParseException
	 */
	public static long getTime(String date, String pattern) throws ParseException {
		if (StringUtils.isBlank(pattern)) {
			pattern = "yyyy-MM-dd";
		}
		SimpleDateFormat sdf = new SimpleDateFormat(pattern);
		return sdf.parse(date).getTime();
	}

	/**
	 * 得到string格式的时间的time
	 * 
	 * @param date
	 * @return
	 * @throws ParseException
	 */
	public static long getTime(String date) throws ParseException {
		return getTime(date, null);
	}

	/**
	 * 格式化时间为字符串
	 * 
	 * @param date
	 * @param pattern
	 * @return
	 * @throws ParseException
	 */
	public static String formatDate(Date date, String pattern) throws ParseException {
		if (StringUtils.isBlank(pattern)) {
			pattern = "yyyy-MM-dd";
		}
		SimpleDateFormat sdf = new SimpleDateFormat(pattern);
		return sdf.format(date);
	}

	/**
	 * 格式化时间为字符串
	 * 
	 * @param date
	 * @return
	 * @throws ParseException
	 */
	public static String formatDate(Date date) throws ParseException {
		return formatDate(date, null);
	}

	/**
	 * 计算两个时间的间隔天数
	 * 
	 * @param prveDate
	 * @param nextDate
	 * @return
	 * @throws ParseException
	 */
	public static int calculationInterval(String prveDateStr, String nextDateStr) throws ParseException {

		SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
		Date prveDate = sdf.parse(prveDateStr);
		Date nextDate = sdf.parse(nextDateStr);

		return (int) Math.abs((nextDate.getTime() - prveDate.getTime()) / (1000 * 3600 * 24));
	}

	public static Timestamp stringToTimestamp(String dateStr) {

		SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
		Calendar cal = Calendar.getInstance();
		try {
			Date date = sdf.parse(dateStr);
			date.getTime();
			cal.setTime(date);
			return new Timestamp(cal.getTimeInMillis());
		} catch (ParseException e) {
			e.printStackTrace();
		}

		cal.setTime(new Date());
		return new Timestamp(cal.getTimeInMillis());
	}

	public static String TimestampToString(Timestamp timestamp, String pattern) {
		if (StringUtils.isEmpty(pattern)) {
			pattern = "yyyy-MM-dd";
		}
		SimpleDateFormat sdf = new SimpleDateFormat(pattern);
		Date date = new Date(timestamp.getTime());
		try {
			return sdf.format(date);
		} catch (Exception e) {
			e.printStackTrace();
		}
		return null;
	}

	/*
	 * date 转换成 XMLGregorianCalendar
	 */
	public static XMLGregorianCalendar long2Gregorian(Date date) {
		if (null == date)
			return null;
		DatatypeFactory dataTypeFactory;
		try {
			dataTypeFactory = DatatypeFactory.newInstance();
		} catch (DatatypeConfigurationException e) {
			throw new RuntimeException(e);
		}
		GregorianCalendar gc = new GregorianCalendar();
		gc.setTimeInMillis(date.getTime());
		return dataTypeFactory.newXMLGregorianCalendar(gc);
	}

	public static String getWeek(Date date, String[] weekSesc) {
		Instant instant = date.toInstant();
		ZoneId zoneId = ZoneId.systemDefault();
		LocalDate localDate = instant.atZone(zoneId).toLocalDate();
		int i = localDate.getDayOfWeek().getValue();
		return weekSesc[i - 1];
	}

	public static class Date2Week {
		String Date;
		String Week;

		public String getDate() {
			return Date;
		}

		public void setDate(String date) {
			Date = date;
		}

		public String getWeek() {
			return Week;
		}

		public void setWeek(String week) {
			Week = week;
		}

	}

	public static boolean isInTimeSpan(Date startTime, Date endTime, Date checkDate) {
		if (-1 == startTime.compareTo(checkDate) && 1 == endTime.compareTo(checkDate))
			return true;
		return false;
	}

}
